package com.lanhao.aot.carrierintegration.dhlpaket;

import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StopWatch;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;

import cn.hutool.core.codec.Base64;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;

/**
  *  最新优化版本  下单
 * @author kunzhou3
 *
 */
public class LatestDHLPaketUtil {
	private static final Logger LOG = LoggerFactory.getLogger(LatestDHLPaketUtil.class);
	
//	private static final String BASE_URL = "https://dconnector-test.dhl.com/api/dvt/open/api/v1/";
//	private static final String UAT_Client_ID = "3a67d01c13f0ebebf590ae31397f044c6712ada9";
//	private static final String UAT_Client_Secret = "3340545c422ca2849082a58cd4b585fd987d7cc1";
//	private static final String PickupAccountId = "HKCYL001";
//	private static final String SoldToAccountId = "HKCYL001";
	
	private static final String BASE_URL = "https://dconnector.dhl.com/api/dvt/open/api/v1/";
	private static final String APP_KEY = "10aee1e0940f5378c9627adac9831368d905e67a";
	private static final String APP_SECRET = "22449418b5e8a4166b261500a1796732c6ab2104";
	private static final String PickupAccountId = "5370617";
	private static final String SoldToAccountId = "521721";
	
	// API名称
	private static final String LABLE_API_NAME = "genericDataAndLabel";
	private static final String TOKEN_API_NAME = "token";
	
	
	private static final String OFFSET_ID = "+08:00";
	private static final String CARRIER = "DHL_Paket";
	private static final DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss" + OFFSET_ID);
	
	
	public static void main(String[] args) {
		String shipmentId = "PLRDE02440308176495-ANHE";
		// 调用token接口url=https://dconnector-test.dhl.com/api/dvt/open/api/v1/token，请求参数request={"grant_type":"client_credentials","client_secret":"3340545c422ca2849082a58cd4b585fd987d7cc1","client_id":"3a67d01c13f0ebebf590ae31397f044c6712ada9"}，返回结果r={"access_token":"d1149c4630f8f6e32b6097976f3507d4","token_type":"Bearer","expires_in":86400}
		Pair<Boolean, String> tokenResult = getAccessToken();
		if(tokenResult.getLeft()) {
			String token = tokenResult.getRight();
			labelOrder(shipmentId, token);
		}
	}

	public static void labelOrder(String shipmentId, String token) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		
		String nowTime = LocalDateTime.now().format(fmt);
		JSONObject request = new JSONObject();
		JSONObject labelRequest = new JSONObject();
		JSONObject hdr = new JSONObject();
		
		hdr.put("messageType", "LABEL");
		hdr.put("messageDateTime", nowTime);
		hdr.put("messageVersion", "1.4");
		hdr.put("messageLanguage", "en");
		labelRequest.put("hdr", hdr);
		
		JSONObject bd = new JSONObject();
		
//		bd.put("customerAccountId", CustomerAccountId);
		bd.put("pickupAccountId", PickupAccountId);
		bd.put("soldToAccountId", SoldToAccountId);
		bd.put("pickupDateTime", nowTime);
		
		bd.put("consolidatedLabelRequired", "Y"); // TODO 新增
		
		JSONObject shipperAddress = new JSONObject();
		shipperAddress.put("companyName", null);
		shipperAddress.put("name", "Benjamin Linden");
		shipperAddress.put("address1", "Kurt-Schumacher-Str. 24");
//		shipperAddress.put("address2", "longcheng Building, No. 20 Bulong Road, Buji Stree");
//		shipperAddress.put("address3", "tFeng Dinglong");
		shipperAddress.put("city", "Hannover");
		shipperAddress.put("state", null);
//		shipperAddress.put("district", "Longgang District");
		shipperAddress.put("country", "DE");
//		shipperAddress.put("phone", "13590152579");
		shipperAddress.put("postCode", "30159");
//		shipperAddress.put("email", "2641454906@qq.com");
		bd.put("shipperAddress", shipperAddress);
		
		JSONArray shipmentItems = new JSONArray();
		JSONObject shipmentItem = new JSONObject();
		JSONObject consigneeAddress = new JSONObject();
		consigneeAddress.put("companyName", null);
		consigneeAddress.put("name", "HUITONG Int. COMPANY,DE-RTN-AE");
		consigneeAddress.put("address1", "Treseburger Str. 22A");
		consigneeAddress.put("address2", null);
		consigneeAddress.put("address3", null);
		consigneeAddress.put("city", "Berlin");
		consigneeAddress.put("state", "BL");
		consigneeAddress.put("district", null);
		consigneeAddress.put("country", "DE");
		consigneeAddress.put("phone", "0000000000");
		consigneeAddress.put("postCode", "13129");
//		consigneeAddress.put("email", "marco_zen@t-online.de");
		
		shipmentItem.put("consigneeAddress", consigneeAddress);
		shipmentItem.put("shipmentID", shipmentId);
		shipmentItem.put("deliveryConfirmationNo", null);
		shipmentItem.put("packageDesc", "ANHE SKU");
		shipmentItem.put("totalWeight", 300);
		shipmentItem.put("totalWeightUOM", "G");
		shipmentItem.put("dimensionUOM", "CM");
		shipmentItem.put("height", null);
		shipmentItem.put("length", null);
		shipmentItem.put("width", null);
		shipmentItem.put("customerReference1", null);
		shipmentItem.put("customerReference2", null);
		shipmentItem.put("workshareIndicator", "HF");
		shipmentItem.put("productCode", "PLR");
		shipmentItem.put("incoterm", "DDP");
		shipmentItem.put("contentIndicator", null);
		shipmentItem.put("totalValue", 5.00);
		shipmentItem.put("currency", "USD");
		shipmentItem.put("remarks", null);
		
		JSONArray shipmentContents = new JSONArray();
		JSONObject shipmentContent = new JSONObject();
		shipmentContent.put("skuNumber", "ANHE SKU");
		shipmentContent.put("description", "ANHE SKU");
		shipmentContent.put("descriptionImport", null);
		shipmentContent.put("descriptionExport", "ANHE SKU");
		shipmentContent.put("itemValue", 5.00);
		shipmentContent.put("itemQuantity", 1);
		shipmentContent.put("grossWeight", null);
		shipmentContent.put("netWeight", null);
		shipmentContent.put("weightUOM", "G");
//		shipmentContent.put("contentIndicator", null);
		shipmentContent.put("countryOfOrigin", "CN");
		shipmentContent.put("hsCode", null);
		shipmentContents.add(shipmentContent);
		
		shipmentItem.put("shipmentContents", shipmentContents);
		
		shipmentItems.add(shipmentItem);
		bd.put("shipmentItems", shipmentItems);
		
		JSONObject label = new JSONObject();
		label.put("pageSize", "400x600");
		label.put("format", "pdf");
		label.put("layout", "1x1");
		bd.put("label", label);
		
		labelRequest.put("bd", bd);
		
		request.put("labelRequest", labelRequest);
		
		Map<String, String> headers = Maps.newConcurrentMap();
		headers.put("Authorization", "Bearer " + token);
		headers.put("Content-Type", "application/json");
		String url = BASE_URL + LABLE_API_NAME;
		String respBody = HttpRequest.post(url).addHeaders(headers).body(request.toJSONString()).timeout(10000).execute().body();
		stopWatch.stop();
		long totalTimeMillis = stopWatch.getTotalTimeMillis();
		LOG.info("请求label接口返回结果 url={}, request={}, result={}，耗时={}ms", url, request.toJSONString(), respBody, totalTimeMillis);
		
		if(StringUtils.isNotBlank(respBody)) {
			JSONObject respObject = JSON.parseObject(respBody);
			Integer status = respObject.getInteger("status");
			if(status != null) {
				String title = respObject.getString("title");
				String details = respObject.getString("details");
				LOG.info("请求面单失败了，失败原因e={}", title + ":" + details);
			} else {
				JSONObject bdObject = respObject.getJSONObject("bd");
				JSONArray labelsArray = bdObject.getJSONArray("labels");
				if(labelsArray != null) {
					JSONObject labelObject = labelsArray.getJSONObject(0);
					JSONObject labelResponseStatus = labelObject.getJSONObject("responseStatus");
					Integer labelStatusCode = labelResponseStatus.getInteger("code");
					if(labelStatusCode == HttpStatus.HTTP_OK) {
						String trackingNo = labelObject.getString("deliveryConfirmationNo");
						String labelURL = labelObject.getString("labelURL");
						String content = labelObject.getString("content");
						LOG.info("获取面单下单成功，shipmentId={}, labelURL={}, content={}", shipmentId, labelURL, content);
						Base64.decodeToFile(content, new File("D:/" + trackingNo + ".pdf"));
					} else {
						String labelMessage = labelResponseStatus.getString("message");
						LOG.info("请求面单失败了，失败原因：message={}", labelMessage);
					}
				} else {
					JSONObject responseStatus = bdObject.getJSONObject("responseStatus");
					String message = responseStatus.getString("message");
					LOG.info("请求面单失败了，失败原因:message={}", message);
				}
			}
			
		}
	}
	
	public static Pair<Boolean, String> getAccessToken() {
		String url = BASE_URL + TOKEN_API_NAME;
		Map<String, Object> formMap = Maps.newHashMap();
		formMap.put("grant_type", "client_credentials");
		formMap.put("client_id", APP_KEY);
		formMap.put("client_secret", APP_SECRET);
		HttpResponse execute = HttpRequest.post(url).form(formMap).setConnectionTimeout(500).setReadTimeout(10000).execute();
		int status = execute.getStatus();
		String respBody = execute.body();
		LOG.info("调用token接口url={}，status={}, 请求参数request={}，返回结果r={}", url, status, JSON.toJSONString(formMap), respBody);
		JSONObject respObject = JSON.parseObject(respBody);
		if (respObject.containsKey("access_token")) {
			String accessToken = respObject.getString("access_token");
			return Pair.of(true, accessToken);
		} else {
			String errorMessage = respObject.getString("message");
			return Pair.of(false, errorMessage);
		}
	}
	
}
